/*
 * Copyright 2010 Alessandro Bellucci
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.soupframework.gwt.designerpanel.client.grid.impl;

import org.soupframework.gwt.designerpanel.client.grid.DesignerPanelGrid;

import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;

public class DivBasedDesignerPanelGrid implements DesignerPanelGrid {

	private int width = -1;
	private int height = -1;
	private int cellWidth = -1;
	private int cellHeight = -1;

	private Element element;

	public DivBasedDesignerPanelGrid(int width, int height, int cellWidth, int cellHeight) {
		super();
		this.width = width;
		this.height = height;
		this.cellWidth = cellWidth;
		this.cellHeight = cellHeight;
		this.createGridDOM();
	}

	public DivBasedDesignerPanelGrid(int cellWidth, int cellHeight) {
		super();
		this.cellWidth = cellWidth;
		this.cellHeight = cellHeight;
	}

	@Override
	public void setGridCellSize(int cellWidth, int cellHeight) {
		this.cellWidth = cellWidth;
		this.cellHeight = cellHeight;
		this.createGridDOM();
	}

	@Override
	public void setPixelHeight(int height) {
		this.height = height;
		this.createGridDOM();
	}

	@Override
	public void setPixelWidth(int width) {
		this.width = width;
		this.createGridDOM();
	}

	@Override
	public GridVertex getClosestGridVertex(int x, int y) {
		int vX = this.cellWidth * ((x + this.cellWidth / 2) / this.cellWidth);
		int vY = this.cellHeight * ((y + this.cellHeight / 2) / this.cellHeight);
		return new GridVertex(vX, vY);
	}

	@Override
	public Element getElement() {
		if(this.element == null){
			this.createGridDOM();
		}
		return this.element;
	}

	private void createGridDOM(){
		if(this.width == -1 || this.height == -1 || this.cellWidth == -1 || this.cellHeight == -1){
			return;
		}

		if(this.element == null){
			this.element = DOM.createDiv();
			Style style = this.element.getStyle();
			style.setPosition(Position.ABSOLUTE);
			style.setLeft(0, Unit.PX);
			style.setTop(0, Unit.PX);
			style.setWidth(width, Unit.PX);
			style.setHeight(height, Unit.PX);
			DOM.setStyleAttribute(this.element, "backgroundColor", "#FFF");
			DOM.setStyleAttribute(this.element, "zIndex", "-999");
		}
		else{
			// removes all children
			while(DOM.getChildCount(this.element) > 0){
				DOM.removeChild(this.element, DOM.getChild(this.element, 0));
			}
		}

		int numX = width / cellWidth;
		int numY = height / cellHeight;
		for(int i = 1 ; i < numY ; i ++){
			Element gridLine = DOM.createDiv();
			Style lineStyle = gridLine.getStyle();
			lineStyle.setPosition(Position.ABSOLUTE);
			lineStyle.setWidth(width, Unit.PX);
			lineStyle.setHeight(1, Unit.PX);
			lineStyle.setLeft(0, Unit.PX);
			lineStyle.setTop(i * this.cellHeight, Unit.PX);
			DOM.setStyleAttribute(gridLine, "backgroundColor", "#DDD");
			DOM.appendChild(this.element, gridLine);
		}
		for(int j = 1 ; j < numX ; j ++){
			Element gridLine = DOM.createDiv();
			Style lineStyle = gridLine.getStyle();
			lineStyle.setPosition(Position.ABSOLUTE);
			lineStyle.setWidth(1, Unit.PX);
			lineStyle.setHeight(height, Unit.PX);
			lineStyle.setLeft(j * this.cellWidth, Unit.PX);
			lineStyle.setTop(0, Unit.PX);
			DOM.setStyleAttribute(gridLine, "backgroundColor", "#DDD");
			DOM.appendChild(this.element, gridLine);
		}
	}

	@Override
	public int getCellHeight() {
		return this.cellHeight;
	}

	@Override
	public int getCellWidth() {
		return this.cellWidth;
	}
}
